const h = (tag, props, children) => {
  // vnode -> javascript对象 -> {}
  return {
    tag,
    props,
    children
  }
}

const mount = (vnode, container) => {
  //1.创建出真是的元素，并且在vnode上保留一份
  const el = vnode.el = document.createElement(vnode.tag)

  //2.处理props
  if (vnode.props) {
    for (const key in vnode.props) {
      const value = vnode.props[key]
      
      if (key.startsWith("on")) {
        el.addEventListener(key.slice(2).toLowerCase(), value)
      } else {
        el.setAttribute(key, value)
      }
    }
  }

  //3.处理children
  if (vnode.children) {
    if (typeof vnode.children === "string") {
      el.textContent = vnode.children
    } else {
      vnode.children.forEach(item => mount(item, el))
    }
  }

  //4.挂载
  container.appendChild(el)

}

const patch = (n1, n2) => {
  if (n1.tag !== n2.tag) {
    const n1ElParent = n1.el.parentElement;
    n1ElParent.removeChild(n1.el);
    mount(n2, n1ElParent)
  } else {
    //1.处理相同tag   取出element,并且在n2中进行保存
    const el = n2.el = n1.el;

    //2.处理props
    const oldProps = n1.props || {}
    const newProps = n2.props || {}

    //2.1 获取所有的newProps添加到el
    for (const key in newProps) {
      const newVal = newProps[key]
      const oldVal = oldProps[key]
      
      if (newVal !== oldVal) {
        if (key.startsWith('on')) {
          el.addEventListener(key.slice(2).toLowerCase, newVal)
        } else {
          el.setAttribute(key, newVal)
        }
      }
    }
    
    //2.2 把旧的props删除
    for (const key in oldProps) {
      if (key.startsWith('on')) {
        el.removeEventListener(key.slice(2), oldProps[key])
      }

      if (!(key in newProps)) {
        el.removeAttribute(key)
      }
    }
    
    //3.处理children
    const oldChildren = n1.children || []
    const newChildren = n2.children || []

    if (typeof newChildren === "string") {  //一：字符串
      if (typeof oldChildren === "string") {
        if (newChildren !== oldChildren) {
          el.textContent = newChildren
        }
      } else {
        el.innerHTML = newChildren
      }
    } else {   //二：数组
      if (typeof oldChildren === "string") {
        el.innerHTML = "";
        newChildren.forEach(item => mount(item, el))
      } else {
        
        const commonlength = Math.min(oldChildren.length, newChildren.length)
        for (let i = 0; i < commonlength; i++) {
          patch(oldChildren[i], newChildren[i])
        }

        if (newChildren.length > oldChildren.length) {
          newChildren.slice(oldChildren.length).forEach(item => mount(item, el))
        }

        if (newChildren.length < oldChildren.length) {
          oldChildren.slice(newChildren.length).forEach(item => el.removeChild(item.el))
        }


      }
    }

  }
}